package cn.wolfcode.service.impl;

import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.common.web.Result;
import cn.wolfcode.domain.OrderInfo;
import cn.wolfcode.domain.Product;
import cn.wolfcode.domain.SeckillProduct;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.fegin.ProductFeignApi;
import cn.wolfcode.mapper.SeckillProductMapper;
import cn.wolfcode.redis.SeckillRedisKey;
import cn.wolfcode.service.ISeckillProductService;
import cn.wolfcode.web.msg.SeckillCodeMsg;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class SeckillProductServiceImpl implements ISeckillProductService {

    @Autowired
    private SeckillProductMapper seckillProductMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ProductFeignApi productFeignApi;

    @Override
    public List<SeckillProductVo> selectTodayByTime(Integer time) {
        //远程调用秒杀服务 获取今天的秒杀商品
        List<SeckillProduct> seckillProducts = seckillProductMapper.queryCurrentlySeckillProduct(time);
        //遍历秒杀商品 获取秒杀商品的productIds
        List<Long> productIds = seckillProducts.stream().map(SeckillProduct::getProductId).collect(Collectors.toList());
        //通过秒杀商品的productIds  获取到product信息
        Result<List<Product>> result = productFeignApi.selectByIds(productIds);
        if (result.hasError() || result.getData()==null){
            throw  new BusinessException(SeckillCodeMsg.SECKILL_PRODUCT_ERROR);
        }
        List<Product> products = result.getData();
        //通过vo 将数据聚集到一起
        List<SeckillProductVo> secKillProductVos = seckillProducts.stream().map(sp -> {
            SeckillProductVo vo = new SeckillProductVo();
            List<Product> list = products.stream().filter(p -> sp.getProductId().equals(p.getId())).collect(Collectors.toList());
            if (list.size() > 0) {
                Product product = list.get(0);
                BeanUtils.copyProperties(product, vo);
            }
            BeanUtils.copyProperties(sp, vo);
            return vo;
        }).collect(Collectors.toList());
        return secKillProductVos;
    }

    @Override
    public List<SeckillProductVo> queryByTime(Integer time) {
        List<String> list = redisTemplate.opsForList().range(SeckillRedisKey.SECKILL_PRODUCT_LIST.join(time + ""), 0, -1);
        if (list == null || list.size() <= 0) {
            log.warn("[秒杀商品]：产生问题 redis缓存出现问题");
            this.selectTodayByTime(time);
        }
        return list.stream().map(p -> {
            return JSON.parseObject(p, SeckillProductVo.class);
        }).collect(Collectors.toList());

    }

    @Override
    public SeckillProductVo queryByTimeAndSeckillId(Integer time, Long seckillId) {
        //远程调用秒杀服务 获取今天的秒杀商品
       SeckillProduct seckillProduct = seckillProductMapper.queryByTimeAndSeckillId(time,seckillId);
        //遍历秒杀商品 获取秒杀商品的productIds
        //通过秒杀商品的productIds  获取到product信息
        Result<List<Product>> result = productFeignApi.selectByIds(Collections.singletonList(seckillProduct.getProductId()));
        if (result.hasError() || result.getData()==null){
            throw  new BusinessException(SeckillCodeMsg.SECKILL_PRODUCT_ERROR);
        }
        List<Product> products = result.getData();
        Product product = products.get(0);
        //通过vo 将数据聚集到一起
        SeckillProductVo vo = new SeckillProductVo();
        BeanUtils.copyProperties(product,vo);
        BeanUtils.copyProperties(seckillProduct,vo);
        return vo;
    }

    @Override
    public int decrStockCount(Long id) {
        return seckillProductMapper.decrStock(id);
    }

    @Override
    public void incryStockCount(Integer time, Long seckillId) {
        seckillProductMapper.incrStock(seckillId);
    }


}
